package com.zd.kids.net;


import com.zd.kids.DataBean.BaseDataBean;
import com.zd.kids.DataBean.BookSeriesDataBean;
import com.zd.kids.DataBean.BookUnitDataBean;
import com.zd.kids.DataBean.CalendarTimeDataBean;
import com.zd.kids.DataBean.CheackAppVersionDataBean;
import com.zd.kids.DataBean.ChecBookCodeDataBean;
import com.zd.kids.DataBean.CommonStatusDataBean;
import com.zd.kids.DataBean.CountryDataBean;
import com.zd.kids.DataBean.MainGroupDataBean;
import com.zd.kids.DataBean.PicBookDataBean;
import com.zd.kids.DataBean.RecodVideoDataBean;
import com.zd.kids.DataBean.TestTrainDataBean;
import com.zd.kids.DataBean.TestTrainWordResultDataBean;
import com.zd.kids.DataBean.TestWordDataBean;
import com.zd.kids.DataBean.TrainTypeDataBean;
import com.zd.kids.DataBean.TrainWordDataBean;
import com.zd.kids.DataBean.UseGuideDataBean;
import com.zd.kids.DataBean.UserInfo;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.ObservableSource;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import okhttp3.ResponseBody;


public class HttpMethod {

    static HttpMethod mHttpMethod;


    public static HttpMethod getIntence() {
        if (mHttpMethod == null) {
            synchronized (HttpMethod.class) {
                if (mHttpMethod == null) {
                    mHttpMethod = new HttpMethod();
                }

            }
        }
        return mHttpMethod;
    }

    public void getCountrys(CustomObserver<List<CountryDataBean>> observer) {
        Observable observable = CustomApi.getIntence().getApi().getCountrys().map(new HttpData<>());
        subscribe(observable, observer);
    }

    public void registcheckBookCode(String inpuCode, CustomObserver<ChecBookCodeDataBean> observer) {
        Observable observable = CustomApi.getIntence().getApi().registcheckBookCode(inpuCode).map(new HttpData<>());
        subscribe(observable, observer);
    }

    public void checkBookCode(String inpuCode, CustomObserver<ChecBookCodeDataBean> observer) {
        Observable observable = CustomApi.getIntence().getApi().checkBookCode(inpuCode).map(new HttpData<>());
        subscribe(observable, observer);
    }

    public void userLogin(String mobile, String countyid, String code, CustomObserver<CommonStatusDataBean> observer) {
        Observable observable = CustomApi.getIntence().getApi().userLogin(mobile, countyid, code).map(new HttpData<>());
        subscribe(observable, observer);
    }

    public void getloginMobileSms(String mobile, String countryid, CustomObserver<String> observer) {
        Observable observable = CustomApi.getIntence().getApi().getloginMobileSms(mobile, countryid).map(new HttpData<>());
        subscribe(observable, observer);
    }

    public void register(Map<String, String> paramMap, CustomObserver<CommonStatusDataBean> observer) {
        Observable observable = CustomApi.getIntence().getApi().register(paramMap).map(new HttpData<>());
        subscribe(observable, observer);
    }

    public void getRecodVideo(String unitid, CustomObserver<RecodVideoDataBean> observer) {
        Observable observable = CustomApi.getIntence().getApi().getRecodVideo(unitid).map(new HttpData<>());
        subscribe(observable, observer);
    }

    public void uploadVideoRecord(Map paramMaps, CustomObserver<TestTrainWordResultDataBean> observer) {
        Observable observable = CustomApi.getIntence().getApi().uploadVideoRecord(paramMaps).map(new HttpData<>());
        subscribe(observable, observer);
    }

    public void registSendSms(String mobile, String countryid, CustomObserver<String> observer) {
        Observable observable = CustomApi.getIntence().getApi().registSendSms(mobile, countryid).map(new HttpData<>());
        subscribe(observable, observer);
    }

    public void getMainGroupDatas(CustomObserver<List<MainGroupDataBean>> observer) {
        Map<String, String> paramMap = new HashMap();
        addCommonParams(paramMap);
        Observable observable = CustomApi.getIntence().getApi().getMainGroupDatas(paramMap).map(new HttpData<>());
        subscribe(observable, observer);
    }

    public void getBookCategorys(String groupId, CustomObserver<BookSeriesDataBean> observer) {
        Map<String, String> map = new HashMap<>();
        addCommonParams(map);
        Observable observable = CustomApi.getIntence().getApi().getBookCategorys(groupId, map).map(new HttpData<>());
        subscribe(observable, observer);
    }

    public void getAiTestTrainDatas(String groupId, String categoryid, CustomObserver<List<TestTrainDataBean>> observer) {
        Observable observable = CustomApi.getIntence().getApi().getAiTestTrainDatas(groupId, categoryid).map(new HttpData<>());
        subscribe(observable, observer);
    }

    public void getBookUnits(String groupId, String categoryid, CustomObserver<BookUnitDataBean> observer) {
        Observable observable = CustomApi.getIntence().getApi().getBookUnits(groupId, categoryid).map(new HttpData<>());
        subscribe(observable, observer);
    }

    public void getTrainList(String unitid, CustomObserver<TrainTypeDataBean> observer) {
        Observable observable = CustomApi.getIntence().getApi().getTrainList(unitid).map(new HttpData<>());
        subscribe(observable, observer);
    }

    public void getNewwordList(String unitid, CustomObserver<TrainWordDataBean> observer) {
        Observable observable = CustomApi.getIntence().getApi().getNewwords(unitid).map(new HttpData<>());
        subscribe(observable, observer);
    }

    public void getUserInfo(CustomObserver<UserInfo> observer) {
        Observable observable = CustomApi.getIntence().getApi().getUserInfo().map(new HttpData<>());
        subscribe(observable, observer);
    }

    public void setPicBookCompleteResult(String unitid, CustomObserver<BaseDataBean> observer) {
        Observable observable = CustomApi.getIntence().getApi().setPicBookCompleteResult(unitid);
        subscribe(observable, observer);
    }

    /**
     * 发送邮件场景，1：预约课堂，2：需要帮助，3：系统邮件
     *
     * @param observer
     */
    public void sendMail(Map map, CustomObserver<String> observer) {
        map.put("scenes", "1");
        Observable observable = CustomApi.getIntence().getApi().sendMail(map).map(new HttpData<>());
        subscribe(observable, observer);
    }

    public void checkApkVersion(CustomObserver<CheackAppVersionDataBean> observer) {
        Observable observable = CustomApi.getIntence().getApi().checkApkVersion("Android").map(new HttpData<>());
        subscribe(observable, observer);
    }

    public void setVideoCompleteResult(String unitid, CustomObserver<BaseDataBean> observer) {
        Observable observable = CustomApi.getIntence().getApi().setVideoCompleteResult(unitid);
        subscribe(observable, observer);
    }

    public void setTrainCompleteResult(String unitid, CustomObserver<BaseDataBean> observer) {
        Observable observable = CustomApi.getIntence().getApi().setTrainCompleteResult(unitid);
        subscribe(observable, observer);
    }

    public void getPicBook(String unitid, CustomObserver<PicBookDataBean> observer) {
        Observable observable = CustomApi.getIntence().getApi().getPicBook(unitid).map(new HttpData<>());
        subscribe(observable, observer);
    }

    public void getTestCompleteResult(String unitid, CustomObserver<BaseDataBean> observer) {
        Observable observable = CustomApi.getIntence().getApi().setTestCompleteResult(unitid);
        subscribe(observable, observer);
    }

    public void setAiCompleteResult(String groupId, String categoryID, CustomObserver<BaseDataBean> observer) {
        Observable observable = CustomApi.getIntence().getApi().setAiCompleteResult(groupId, categoryID);
        subscribe(observable, observer);
    }

    public void getCalendarData(CustomObserver<List<CalendarTimeDataBean>> observer) {
        Observable observable = CustomApi.getIntence().getApi().getCalendarData().map(new HttpData<>());
        subscribe(observable, observer);
    }

    public void uploadTestRecord(Map<String, String> map, CustomObserver<BaseDataBean> observer) {
        Observable observable = CustomApi.getIntence().getApi().uploadTestRecord(map);
        subscribe(observable, observer);
    }

    public void getVideoGuide(String unitId, CustomObserver<UseGuideDataBean> observer) {
        Observable observable = CustomApi.getIntence().getApi().getVideoGuide(unitId).map(new HttpData<>());
        subscribe(observable, observer);
    }

    public void getScanWords(String newwordid, CustomObserver<TrainWordDataBean> observer) {
        Observable observable = CustomApi.getIntence().getApi().getScanWords(newwordid).map(new HttpData<>());
        subscribe(observable, observer);
    }

    public void getTestWords(String unitid, CustomObserver<TestWordDataBean> observer) {
        Observable observable = CustomApi.getIntence().getApi().getTestWords(unitid).map(new HttpData<>());
        subscribe(observable, observer);
    }


    public Observable getDownFileObservable(String url, File file, Observer<Integer> observer) {
        return CustomApi.getIntence().getApi()
                .downloadApk("Encoding", url)
                .subscribeOn(Schedulers.io())
                .flatMap(new Function<ResponseBody, ObservableSource<Integer>>() {
                    @Override
                    public ObservableSource<Integer> apply(ResponseBody responseBody) throws Exception {
                        return Observable.create(new ObservableOnSubscribe<Integer>() {
                            @Override
                            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                                long totalLength = responseBody.contentLength();
                                InputStream inputStream = responseBody.byteStream();
                                OutputStream os = null;
                                long currentLength = 0;
                                try {
                                    os = new BufferedOutputStream(new FileOutputStream(file));
                                    byte data[] = new byte[2048];
                                    int len;

                                    while ((len = inputStream.read(data)) != -1) {
                                        os.write(data, 0, len);
                                        currentLength += len;
                                        //计算当前下载进度
                                        int progress = (int) (100 * currentLength / totalLength);
                                        emitter.onNext((int) (progress));
                                    }

                                } catch (IOException e) {
                                    e.printStackTrace();
                                    emitter.onError(e);
                                } finally {
                                    try {
                                        inputStream.close();
                                    } catch (IOException e) {
                                        e.printStackTrace();
                                    }
                                    try {
                                        if (os != null) {
                                            os.close();
                                        }
                                    } catch (IOException e) {
                                        e.printStackTrace();
                                    }
                                    emitter.onComplete();
                                }
                            }

                        });
                    }
                });
    }

    public void downFile(String url, File file, Observer<Integer> observer) {
        getDownFileObservable(url, file, observer)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(observer);
    }

    private void addCommonParams(Map<String, String> prarms) {

    }

    private void subscribe(Observable observable, Observer observer) {
        observable.observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
                .subscribe(observer);
    }


    class HttpData<T> implements Function<BaseDataBean<T>, T> {
        @Override
        public T apply(BaseDataBean<T> tBaseDataBean) throws Exception {
            if (tBaseDataBean.getCode() == 200 && tBaseDataBean.getData() == null) {
                return null;
            } else if (tBaseDataBean.getCode() == 200) {
                return tBaseDataBean.getData();
            } else {
                throw new BusinessException(tBaseDataBean.getMessage(), tBaseDataBean.getCode() + "");
            }

        }
    }


}
